package com.example.myapplication.data

/**
 * A generic class that holds a value with its loading status.
 * 开发中经常需要在代码中声明一些有限集合，如：网络请求可能为失败或成功；用户账号是高级用户或者普通用户。

可以使用枚举来实现这类模型，但枚举自身存在很多限制。枚举类型每个值只允许有一个实例，同时枚举也无法为每个类型添加额外的信息。
也可以使用一个抽象类然后让一些类继承它，这样就可以随意扩展，但这会失去枚举所带来的有限集合的优势。
而sealed class则同时包含前面两者的优势——抽象类表示的灵活性和枚举里集合的受限性。

密封类的基本使用
和抽象类类似，密封类可用于表示层级关系。子类可以是任意的类：数据类(data class)、kotlin对象(object)、普通的类，
也可以是另一个密封类。但不同于抽象类的是，必须把层级声明在同一个文件中，或者嵌套在类的内部：

尝试在密封类所定义的文件外继承类则会导致编译错误。
 * @param <T>
 */
sealed class Result<out T : Any> {

    data class Success<out T : Any>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()

    override fun toString(): String {
        return when (this) {
            is Success<*> -> "Success[data=$data]"
            is Error -> "Error[exception=$exception]"
        }
    }
}